package bannersrvlogic

import (
	"context"
	"math"
	"strings"

	"gozero-microservices/common-service/rpc/internal/model"
	"gozero-microservices/common-service/rpc/internal/svc"
	"gozero-microservices/common-service/rpc/types"
	"gozero-microservices/common-service/rpc/types/common"
	"gozero-microservices/common-service/rpc/utils"

	"github.com/zeromicro/go-zero/core/logx"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

type BannerLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

/**
 * 创建横幅逻辑实例
 *
 * @param context.Context ctx ----------------------必传
 * @param *svc.ServiceContext svcCtx ---------------必传
 * @return *BannerLogic
 * @author huwl
 * @date 2025/10/14 12:54:03
 */
func NewBannerLogicInstance(ctx context.Context, svcCtx *svc.ServiceContext) *BannerLogic {
	return &BannerLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

/**
 * 新增
 *
 * @param string Title ------------------------必传,标题
 * @param string ImageUrl ---------------------非必传,图片
 * @param uint32 Type -------------------------非必传,类型
 * @param string Link -------------------------非必传,链接
 * @param uint32 Sort -------------------------非必传,排序
 * @param int32 Status ------------------------非必传,状态
 * @param string Note -------------------------非必传,备注
 * @return *common.Result, error
 * @author huwl
 * @date 2025/10/20 18:51:38
 */
func (l *BannerLogic) AddBanner(in *common.AddBannerRequest) (*common.Result, error) {
	if in.Title == "" {
		return nil, status.Errorf(codes.InvalidArgument, "标题不能为空")
	}

	// 操作数据库
	_, err := l.svcCtx.BannerModel.Insert(l.ctx, &model.MallBanner{
		Title:      in.Title,
		ImageUrl:   in.ImageUrl,
		Type:       uint8(in.Type),
		Link:       in.Link,
		Sort:       int8(in.Sort),
		Status:     int8(in.Status),
		Note:       in.Note,
		CreateTime: types.Now(),
	})
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	return &common.Result{
		Code: 200,
		Msg:  "新增横幅成功",
	}, nil
}

/**
 * 删除
 *
 * @param string Ids --------------------------必传,Id支持多个
 * @return *common.Result, error
 * @author huwl
 * @date 2025/10/22 10:15:55
 */
func (l *BannerLogic) DeleteBanner(in *common.DeleteRequest) (*common.Result, error) {
	if in.Ids == "" {
		return nil, status.Errorf(codes.InvalidArgument, "Id错误")
	}

	// 操作数据库
	err := l.svcCtx.BannerModel.EditByParams(l.ctx, map[string]interface{}{
		"status": -2,
	}, map[string]interface{}{
		"id IN (?)": utils.IntSplit(strings.TrimRight(in.Ids, ","), ","),
	})
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	return &common.Result{
		Code: 200,
		Msg:  "删除横幅成功",
	}, nil
}

/**
 * 编辑
 *
 * @param uint32 Id ---------------------------必传,Id
 * @param string Title ------------------------非必传,标题
 * @param string ImageUrl ---------------------非必传,图片
 * @param uint32 Type -------------------------非必传,类型
 * @param string Link -------------------------非必传,链接
 * @param string Note -------------------------非必传,备注
 * @param uint32 Sort -------------------------非必传,排序
 * @return *common.Result, error
 * @author huwl
 * @date 2025/10/22 10:15:55
 */
func (l *BannerLogic) EditBanner(in *common.EditBannerRequest) (*common.Result, error) {
	if in.Id <= 0 {
		return nil, status.Errorf(codes.InvalidArgument, "Id错误")
	}

	params := map[string]interface{}{}
	if in.Title != "" {
		params["title"] = in.Title
	}
	if in.ImageUrl != "" {
		params["image_url"] = in.ImageUrl
	}
	if in.Type > 0 {
		params["type"] = in.Type
	}
	if in.Link != "" {
		params["link"] = in.Link
	}
	if in.Note != "" {
		params["note"] = in.Note
	}
	if in.Sort > 0 {
		params["sort"] = in.Sort
	}

	err := l.svcCtx.BannerModel.EditByPrimaryKey(l.ctx, params, in.Id)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	return &common.Result{
		Code: 200,
		Msg:  "编辑横幅成功",
	}, nil
}

/**
 * 编辑状态
 *
 * @param string Ids --------------------------必传,Id支持多个
 * @return *common.Result, error
 * @author huwl
 * @date 2025/10/22 10:15:55
 */
func (l *BannerLogic) EditStatusBanner(in *common.EditStatusRequest) (*common.Result, error) {
	ids := strings.TrimRight(in.Ids, ",")
	if ids == "" {
		return nil, status.Errorf(codes.InvalidArgument, "Id错误")
	}
	if !utils.IsContainNumber[int8]([]int8{-1, 1}, int8(in.Status)) {
		return nil, status.Errorf(codes.InvalidArgument, "状态错误")
	}

	// 操作数据库
	err := l.svcCtx.BannerModel.EditByParams(l.ctx, map[string]interface{}{
		"status": in.Status,
	}, map[string]interface{}{
		"id IN (?)": utils.IntSplit(ids, ","),
	})
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	message := ""
	if in.Status == 1 {
		message = "启用"
	} else {
		message = "禁用"
	}

	return &common.Result{
		Code: 200,
		Msg:  message + "横幅成功",
	}, nil
}

/**
 * 详情
 *
 * @param uint64 Id ---------------------------必传,Id
 * @return *common.Banner, error
 * @author huwl
 * @date 2025/10/22 10:15:55
 */
func (l *BannerLogic) BannerDetail(in *common.DetailRequest) (*common.Banner, error) {
	if in.Id <= 0 {
		return nil, status.Errorf(codes.InvalidArgument, "Id错误")
	}

	// 操作数据库
	bannerRes, err := l.svcCtx.BannerModel.FindOne(l.ctx, int64(in.Id))
	if err != nil {
		if strings.Contains(err.Error(), "no rows in result set") {
			return nil, status.Errorf(codes.Aborted, "横幅信息错误")
		}

		return nil, status.Errorf(codes.Aborted, err.Error())
	}
	if bannerRes.Status == -2 {
		return nil, status.Errorf(codes.Aborted, "横幅信息错误")
	}

	// 组装数据
	return &common.Banner{
		Id:         uint32(bannerRes.Id),
		Title:      bannerRes.Title,
		ImageUrl:   bannerRes.ImageUrl,
		Type:       uint32(bannerRes.Type),
		Link:       bannerRes.Link,
		Note:       bannerRes.Note,
		Sort:       uint32(bannerRes.Sort),
		Status:     int32(bannerRes.Status),
		CreateTime: bannerRes.CreateTime.String(),
		UpdateTime: bannerRes.UpdateTime.String(),
	}, nil
}

/**
 * 列表
 *
 * @param uint32 Id ---------------------------非必传,Id
 * @param string Ids --------------------------非必传,Id支持多个
 * @param string Title ------------------------非必传,标题
 * @param string Type -------------------------非必传,类型
 * @param string Status -----------------------非必传,状态
 * @param string StartCreateTime --------------非必传,开始创建时间
 * @param string EndCreateTime ----------------非必传,结束创建时间
 * @param string SortField --------------------非必传,排序字段
 * @param string SortType ---------------------非必传,排序方式
 * @param int32 PageSize ----------------------非必传,条数
 * @param uint32 Page -------------------------非必传,页码
 * @return *common.BannerListResult, error
 * @author huwl
 * @date 2025/10/22 10:15:55
 */
func (l *BannerLogic) BannerList(in *common.QueryBannerRequest) (*common.BannerListResult, error) {
	params := map[string]interface{}{
		"status <> ?": -2,
	}

	page := in.Page
	pageSize := in.PageSize
	sortType := in.SortType
	sortField := in.SortField
	if in.Id > 0 {
		params["id"] = in.Id
	}
	if in.Ids != "" {
		params["id IN (?)"] = utils.IntSplit(strings.TrimRight(in.Ids, ","), ",")
	}
	if in.Type != "" {
		params["type IN (?)"] = utils.IntSplit(strings.TrimRight(in.Type, ","), ",")
	}
	if in.Status != "all" {
		params["status IN (?)"] = utils.IntSplit(in.Status, ",")
	}
	if in.StartCreateTime != "" {
		params["create_time >= ?"] = in.StartCreateTime + " 00:00:00"
	}
	if in.EndCreateTime != "" {
		params["create_time <= ?"] = in.EndCreateTime + " 23:59:59"
	}
	if page <= 0 {
		page = 1
	}
	if pageSize == 0 {
		pageSize = 20
	}
	if sortField == "" {
		sortField = "id"
	}
	if sortType == "" {
		sortType = "desc"
	}

	// 查询数量
	total, err := l.svcCtx.BannerModel.GetResultsByTotal(l.ctx, params)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}

	var banners []*model.MallBanner
	if total > 0 {
		err = l.svcCtx.BannerModel.GetResultsByParams(l.ctx, &banners, params, page, int8(pageSize), sortField+" "+sortType)
		if err != nil {
			return nil, status.Errorf(codes.Aborted, err.Error())
		}
	}

	// 组装数据
	bannerItems := []*common.Banner{}
	for _, banner := range banners {
		bannerItems = append(bannerItems, &common.Banner{
			Id:         uint32(banner.Id),
			Title:      banner.Title,
			ImageUrl:   banner.ImageUrl,
			Type:       uint32(banner.Type),
			Link:       banner.Link,
			Note:       banner.Note,
			Sort:       uint32(banner.Sort),
			Status:     int32(banner.Status),
			CreateTime: banner.CreateTime.String(),
			UpdateTime: banner.UpdateTime.String(),
		})
	}

	// 计算总页数
	pageTotal := math.Ceil(float64(total) / float64(pageSize))

	return &common.BannerListResult{
		Page:      page,
		PageSize:  pageSize,
		Total:     int32(total),
		PageTotal: int32(pageTotal),
		Banners:   bannerItems,
	}, nil
}

/**
 * 列表
 *
 * @param uint32 Id ---------------------------非必传,Id
 * @param string Ids --------------------------非必传,Id支持多个
 * @param string Title ------------------------非必传,标题
 * @param string Type -------------------------非必传,类型
 * @param string Status -----------------------非必传,状态
 * @param string StartCreateTime --------------非必传,开始创建时间
 * @param string EndCreateTime ----------------非必传,结束创建时间
 * @return *common.TotalResult, error
 * @author huwl
 * @date 2025/10/22 10:15:55
 */
func (l *BannerLogic) BannerTotal(in *common.QueryBannerRequest) (*common.TotalResult, error) {
	params := map[string]interface{}{
		"status <> ?": -2,
	}

	if in.Id > 0 {
		params["id"] = in.Id
	}
	if in.Ids != "" {
		params["id IN (?)"] = utils.IntSplit(strings.TrimRight(in.Ids, ","), ",")
	}
	if in.Type != "" {
		params["type IN (?)"] = utils.IntSplit(strings.TrimRight(in.Type, ","), ",")
	}
	if in.Status != "all" {
		params["status IN (?)"] = utils.IntSplit(in.Status, ",")
	}
	if in.StartCreateTime != "" {
		params["create_time >= ?"] = in.StartCreateTime + " 00:00:00"
	}
	if in.EndCreateTime != "" {
		params["create_time <= ?"] = in.EndCreateTime + " 23:59:59"
	}

	// 查询数量
	total, err := l.svcCtx.BannerModel.GetResultsByTotal(l.ctx, params)
	if err != nil {
		return nil, status.Errorf(codes.Aborted, err.Error())
	}
	return &common.TotalResult{Total: uint32(total)}, nil
}
